home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / gs3.53 / gs_res.ps < prev    next >
Text File  |  1996-01-10  |  14KB  |  519 lines

  1. %    Copyright (C) 1994, 1995 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % Initialization file for Level 2 resource machinery.
  16. % When this is run, systemdict is still writable,
  17. % but everything defined here goes into level2dict.
  18.  
  19. level2dict begin
  20.  
  21. (BEGIN RESOURCES) VMDEBUG
  22.  
  23. % We keep track of (global) instances with another entry in the resource
  24. % dictionary, an Instances dictionary.  For categories with implicit
  25. % instances, the values in Instances are the same as the keys;
  26. % for other categories, the values are [instance status size].
  27.  
  28. % Note that the dictionary that defines a resource category is stored
  29. % in global memory.  The PostScript manual says that each category must
  30. % manage global and local instances separately.  However, objects in
  31. % global memory other than systemdict can't reference objects in local memory.
  32. % This means that the resource category dictionary, which would otherwise be
  33. % the obvious place to keep track of the instances, can't be used to keep
  34. % track of local instances.  Instead, we define a dictionary in local VM
  35. % called localinstancedict, in which the key is the category name and
  36. % the value is the analogue of Instances for local instances.
  37.  
  38. % We don't currently implement automatic resource unloading.
  39. % When and if we do, it should be hooked to the garbage collector.
  40. % However, Ed Taft of Adobe says their interpreters don't implement this
  41. % either, so we aren't going to worry about it for a while.
  42.  
  43. currentglobal false setglobal systemdict begin
  44.   /localinstancedict 5 dict def
  45. end true setglobal
  46. /.emptydict 0 dict readonly def
  47. setglobal
  48.  
  49. % Resource category dictionaries have the following keys (those marked with
  50. % * are optional):
  51. %    Standard, defined in the Red Book:
  52. %        Category (name)
  53. %        *InstanceType (name)
  54. %        DefineResource
  55. %        UndefineResource
  56. %        FindResource
  57. %        ResourceStatus
  58. %        ResourceForAll
  59. %        *ResourceFileName
  60. %    Additional, specific to our implementation:
  61. %        Instances (dictionary)
  62. %        .LocalInstances
  63. %            - .LocalInstances <dict>
  64. %        .GetInstance
  65. %            <key> .GetInstance <instance> -true-
  66. %            <key> .GetInstance -false-
  67. %        .CheckResource
  68. %            <value> .CheckResource <ok>
  69. %        .DoLoadResource
  70. %            <key> .DoLoadResource - (may give an error)
  71. %        .LoadResource
  72. %            <key> .LoadResource - (may give an error)
  73. %        .ResourceFile
  74. %            <key> .ResourceFile <file> -true-
  75. %            <key> .ResourceFile <key> -false-
  76. % All the above procedures expect that the top dictionary on the d-stack
  77. % is the resource dictionary.
  78.  
  79. % Define enough of the Category category so we can define other categories.
  80. % The dictionary we're about to create will become the Category
  81. % category definition dictionary.
  82.  
  83. 12 dict begin
  84.  
  85.         % Standard entries
  86.  
  87. /Category /Category def
  88. /InstanceType /dicttype def
  89.  
  90. /DefineResource
  91.     { dup .CheckResource
  92.        { dup /Category 3 index cvlit .growput readonly
  93.          dup [ exch 0 -1 ] exch
  94.          Instances 4 2 roll put
  95.        }
  96.        { /typecheck signalerror
  97.        }
  98.       ifelse
  99.     } bind def
  100. /FindResource        % (redefined below)
  101.     { Instances exch get 0 get
  102.     } bind def
  103.  
  104.         % Additional entries
  105.  
  106. /Instances 25 dict def
  107. Instances /Category [currentdict 0 -1] put
  108.  
  109. /.LocalInstances 0 dict def
  110. /.GetInstance
  111.     { Instances exch .knownget
  112.     } bind def
  113. /.CheckResource
  114.     { dup gcheck currentglobal and
  115.        { /DefineResource /FindResource /ResourceForAll /ResourceStatus
  116.          /UndefineResource }
  117.        { 2 index exch known and }
  118.       forall exch pop
  119.     } bind def
  120.  
  121. Instances end begin    % for the base case of findresource
  122.  
  123. (END CATEGORY) VMDEBUG
  124.  
  125. % Define the resource operators.  I don't see how we can possibly restore
  126. % the stacks after an error, since the procedure may have popped and
  127. % pushed elements arbitrarily....
  128.  
  129. mark
  130. /defineresource        % <key> <instance> <category> defineresource <instance>
  131.     { /Category findresource dup begin
  132.       /InstanceType known
  133.        { dup type InstanceType ne
  134.           { dup type /packedarraytype eq InstanceType /arraytype eq and
  135.         not { /typecheck signalerror } if
  136.           } if
  137.        } if
  138.       /DefineResource load stopped end { stop } if
  139.     }
  140. /findresource        % <key> <category> findresource <instance>
  141.     { dup /Category eq
  142.        { pop //Category 0 get } { /Category findresource } ifelse
  143.       begin
  144.       /FindResource load stopped end { stop } if
  145.     }
  146. /resourceforall        % <template> <proc> <scratch> <category> resourceforall -
  147.     { /Category findresource begin
  148.       /ResourceForAll load stopped end { stop } if
  149.     }
  150. /resourcestatus        % <key> <category> resourcestatus <status> <size> true
  151.             % <key> <category> resourcestatus false
  152.     { /Category findresource begin
  153.       /ResourceStatus load stopped end { stop } if
  154.     }
  155. /undefineresource    % <key> <category> undefineresource -
  156.     { /Category findresource begin
  157.       /UndefineResource load stopped end { stop } if
  158.     }
  159. end        % Instances of Category
  160. counttomark 2 idiv { bind odef } repeat pop
  161.  
  162. % Define the Generic category.
  163.  
  164. /Generic mark
  165.  
  166.         % Standard entries
  167.  
  168. % We're still running in Level 1 mode, so dictionaries won't expand.
  169. % Leave room for the /Category entry.
  170. /Category null
  171.  
  172. /DefineResource
  173.     { dup .CheckResource
  174.        { dup [ exch 0 -1 ] exch
  175.          currentglobal
  176.           { false setglobal 2 index UndefineResource    % remove local def if any
  177.         true setglobal
  178.         Instances dup //.emptydict eq
  179.          { pop 3 dict /Instances 1 index def
  180.          }
  181.         if
  182.           }
  183.           { .LocalInstances dup //.emptydict eq
  184.              { pop 3 dict localinstancedict Category 2 index put
  185.          }
  186.         if
  187.           }
  188.          ifelse
  189.          4 2 roll .growput
  190.        }
  191.        { /typecheck signalerror
  192.        }
  193.       ifelse
  194.     } bind
  195. /UndefineResource
  196.     {  { dup 2 index .knownget
  197.           { dup 1 get 1 ge
  198.          { dup 0 null put 1 2 put pop pop }
  199.          { pop exch undef }
  200.         ifelse
  201.           }
  202.           { pop pop
  203.           }
  204.          ifelse
  205.        }
  206.       currentglobal
  207.        { 2 copy Instances exch exec
  208.        }
  209.       if .LocalInstances exch exec
  210.     } bind
  211. /FindResource
  212.     { dup ResourceStatus
  213.        { pop 1 gt            % not in VM
  214.           { .DoLoadResource
  215.           }
  216.          if
  217.          .GetInstance pop        % can't fail
  218.          0 get
  219.        }
  220.        { /undefinedresource signalerror
  221.        }
  222.       ifelse
  223.     } bind
  224. /ResourceStatus
  225.     { dup .GetInstance
  226.        { exch pop dup 1 get exch 2 get true }
  227.        { .ResourceFile
  228.           { closefile 2 -1 true }
  229.           { pop false }
  230.          ifelse
  231.        }
  232.       ifelse
  233.     } bind
  234. /ResourceForAll
  235.     { % **************** Doesn't present instance groups in
  236.       % **************** the correct order yet.
  237.       % We construct a new procedure so we don't have to use
  238.       % static resources to hold the iteration state.
  239.       3 packedarray        % template, proc, scratch
  240.       { exch pop    % stack contains: key, {template, proc, scratch}
  241.         2 copy 0 get .stringmatch
  242.          { 1 index type dup /stringtype eq exch /nametype eq or
  243.         { 2 copy 2 get cvs
  244.           exch 1 get 3 -1 roll pop
  245.         }
  246.         { 1 get
  247.         }
  248.            ifelse exec
  249.          }
  250.          { pop pop
  251.          }
  252.         ifelse
  253.       } /exec cvx 3 packedarray cvx
  254.       % We must pop the resource dictionary off the dict stack
  255.       % when doing the actual iteration, and restore it afterwards.
  256.       currentglobal .LocalInstances length 0 eq or not
  257.        {        % We must do local instances, and do them first.
  258.          /forall cvx 1 index currentdict 3 packedarray cvx
  259.          .LocalInstances 3 1 roll end exec begin
  260.        }
  261.       if
  262.       Instances exch
  263.       /forall cvx currentdict 2 packedarray cvx
  264.       end exec begin
  265.     } bind
  266.  
  267.         % Additional entries
  268.  
  269. % Unfortunately, we can't create the real Instances dictionary now,
  270. % because if someone copies the Generic category (which pp. 95-96 of the
  271. % 2nd Edition Red Book says is legitimate), they'll wind up sharing
  272. % the Instances.  Instead, we have to create Instances on demand,
  273. % just like the entry in localinstancedict.
  274. % We also have to prevent anyone from creating instances of Generic itself.
  275. /Instances //.emptydict
  276.  
  277. /.LocalInstances
  278.     { localinstancedict Category .knownget not { //.emptydict } if
  279.     } bind
  280. /.GetInstance
  281.     { currentglobal
  282.        { Instances exch .knownget }
  283.        { .LocalInstances 1 index .knownget
  284.           { exch pop true }
  285.           { Instances exch .knownget }
  286.          ifelse
  287.        }
  288.       ifelse
  289.     } bind
  290. /.CheckResource
  291.     { pop true
  292.     } bind
  293. /.DoLoadResource
  294.     { dup vmstatus pop exch pop exch
  295.       .LoadResource
  296.       vmstatus pop exch pop exch sub
  297.       1 index .GetInstance not
  298.        { pop /undefinedresource signalerror }    % didn't load
  299.       if
  300.       dup 1 1 put
  301.       2 3 -1 roll put
  302.     } bind
  303. /.LoadResource
  304.     { dup .ResourceFile
  305.        { exch pop currentglobal
  306.           { run }
  307.           { true setglobal { run } stopped false setglobal { stop } if }
  308.          ifelse
  309.        }
  310.        { /undefinedresource signalerror
  311.        }
  312.      ifelse
  313.     } bind
  314. /.ResourceFile
  315.     { currentdict /ResourceFileName known
  316.        { mark 1 index 100 string { ResourceFileName }
  317.          stopped
  318.           { cleartomark false }
  319.           { exch pop findlibfile
  320.          { exch pop exch pop true }
  321.          { false }
  322.         ifelse
  323.           }
  324.          ifelse
  325.        }
  326.        { false }
  327.       ifelse
  328.     } bind
  329.  
  330. .dicttomark
  331. /Category defineresource pop
  332.  
  333. % Fill in the rest of the Category category.
  334. /Category /Category findresource dup
  335. /Generic /Category findresource begin
  336.  { /FindResource /ResourceForAll /ResourceStatus /UndefineResource /.ResourceFile }
  337.  { dup load put dup } forall
  338. pop readonly pop end
  339.  
  340. (END GENERIC) VMDEBUG
  341.  
  342. % Define the fixed categories.
  343.  
  344. mark
  345.     % Things other than types
  346.  /ColorSpaceFamily
  347.    mark colorspacedict { pop } forall .packtomark
  348.  /Emulator
  349.    mark EMULATORS { cvn } forall .packtomark
  350.  /Filter
  351.    mark filterdict { pop } forall .packtomark
  352.  /IODevice
  353.     % Loop until the .getiodevice gets a rangecheck.
  354.    errordict /rangecheck 2 copy get
  355.    errordict /rangecheck { pop stop } put    % pop the command
  356.    mark 0 { {dup .getiodevice exch 1 add} loop} stopped pop pop pop .packtomark
  357.    4 1 roll put
  358.    .clearerror
  359.     % Types
  360.  /setcolorrendering where
  361.   { pop /ColorRenderingType
  362.      {1}
  363.   } if
  364. buildfontdict 0 known
  365.   { /FMapType
  366.      {2 3 4 5 6 7 8}
  367.   } if
  368.  /FontType
  369.    [ buildfontdict { pop } forall ]
  370.  /FormType
  371.    {1}
  372.  /HalftoneType
  373.    {1 2 3 4 5}
  374.  /ImageType
  375.    {1}
  376.  /PatternType
  377.    {1}            % should check for Pattern color space
  378. counttomark 2 idiv
  379.  { mark
  380.  
  381.         % Standard entries
  382.  
  383.    /DefineResource
  384.     { /invalidaccess signalerror } bind
  385.    /UndefineResource
  386.     { /invalidaccess signalerror } bind
  387.    /FindResource
  388.     { Instances exch get } bind
  389.    /ResourceStatus
  390.     { Instances exch known { 0 0 true } { false } ifelse } bind
  391.    /ResourceForAll
  392.     /Generic /Category findresource /ResourceForAll get
  393.  
  394.         % Additional entries
  395.  
  396.    counttomark 2 add -1 roll
  397.    dup length dict dup begin exch { dup def } forall end readonly
  398.    /Instances exch
  399.    /.LocalInstances    % used by ResourceForAll
  400.     0 dict def
  401.  
  402.    .dicttomark /Category defineresource pop
  403.  } repeat pop
  404.  
  405. (END FIXED) VMDEBUG
  406.  
  407. % Define the other built-in categories.
  408.  
  409. /.definecategory    % <name> -mark- <key1> ... <valuen> .definecategory -
  410.  { counttomark 2 idiv 2 add        % Instances, Category
  411.    /Generic /Category findresource dup maxlength 3 -1 roll add dict copy begin
  412.    counttomark 2 idiv { def } repeat pop    % pop the mark
  413.    currentdict end /Category defineresource pop
  414.  } bind def
  415.  
  416. /ColorRendering mark /InstanceType /dicttype .definecategory
  417. /ColorSpace mark /InstanceType /arraytype .definecategory
  418. /Form mark /InstanceType /dicttype .definecategory
  419. /Halftone mark /InstanceType /dicttype .definecategory
  420. /Pattern mark /InstanceType /dicttype .definecategory
  421. /ProcSet mark /InstanceType /dicttype .definecategory
  422.  
  423. (END MISC) VMDEBUG
  424.  
  425. % Define the Encoding category.
  426.  
  427. /Encoding mark
  428.  
  429. /InstanceType /arraytype
  430.  
  431. % Handle already-registered encodings, including lazily loaded encodings
  432. % that aren't loaded yet.
  433.  
  434. /Instances mark
  435.   EncodingDirectory
  436.    { dup length 256 eq { [ exch 0 -1 ] } { pop [null 2 -1] } ifelse
  437.    } forall
  438. .dicttomark
  439.  
  440. /.ResourceFileDict mark
  441.   EncodingDirectory
  442.    { dup length 256 eq { pop pop } { 0 get } ifelse
  443.    } forall
  444. .dicttomark
  445.  
  446. /ResourceFileName
  447.  { exch dup .ResourceFileDict exch .knownget
  448.     { exch pop exch copy }
  449.     { exch pop /undefinedresource signalerror }
  450.    ifelse
  451.  } bind
  452.  
  453. .definecategory            % Encoding
  454.  
  455. /.findencoding { /Encoding findresource } bind def
  456. /findencoding /.findencoding load odef
  457. /.defineencoding
  458.  { 2 copy /Encoding defineresource pop
  459.    //EncodingDirectory 3 1 roll put
  460.  } bind def
  461.  
  462. (END ENCODING) VMDEBUG
  463.  
  464. % Define the Font category.
  465.  
  466. /Font mark
  467.  
  468. /InstanceType /dicttype
  469.  
  470. /DefineResource
  471.     { 2 copy //definefont exch pop
  472.       /Generic /Category findresource /DefineResource get exec
  473.     } bind
  474. /UndefineResource
  475.     { dup //undefinefont
  476.       /Generic /Category findresource /UndefineResource get exec
  477.     } bind
  478. /FindResource
  479.     { dup ResourceStatus
  480.        { pop 1 gt { .DoLoadResource } if }
  481.        { .DoLoadResource }
  482.       ifelse
  483.       .GetInstance pop 0 get
  484.     } bind
  485.  
  486. /.LoadResource
  487.     { //findfont exec pop
  488.     } bind
  489.  
  490. /Instances FontDirectory length 2 mul dict
  491.  
  492. .definecategory            % Font
  493.  
  494. % Redefine font "operators".
  495. /.definefontmap
  496.  { /Font /Category findresource /Instances get
  497.    dup 3 index known
  498.     { pop }
  499.     { 2 index [null 2 -1] .growput }
  500.    ifelse
  501.    //.definefontmap exec
  502.  } bind def
  503.  
  504. /definefont
  505.     { /Font defineresource } bind odef
  506. /undefinefont
  507.     { /Font undefineresource } bind odef
  508. /findfont
  509.     { /Font findresource } bind def    % Must be a procedure, not an operator
  510.  
  511. % Remove initialization utilities.
  512. currentdict /.definecategory undef
  513. currentdict /.emptydict undef
  514.  
  515. end                % level2dict
  516.